<%
' +----------------------------------------------------------------------
' | POPASP [ ASP MVC ]
' +----------------------------------------------------------------------
' | Copyright (c) 2016 http://popasp.com All rights reserved.
' +----------------------------------------------------------------------
' | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
' +----------------------------------------------------------------------
' | Author: popasp <1737025626@qq.com>
' +----------------------------------------------------------------------
Class POPASP_TEMPLATE
	private fso
	public tpl_vars,tpl_vars_json
	
	'是否启用模板布局
	Public layout_on
	
	'模板布局文件
	Public layout_file
	
	'模板布局替换标签
	Public layout_label
	
	'不需要模板布局的替换标签
	Public nolayout_label
	
	' session 中允许的最大字符个数
	Public session_length
	
	Private poplite_path
	
	Private poplite_end_path
	
	' The name of the diretory where temp file are located
	' @var string
	public temp_dir
  
	' The name of the diretory where templates are located
	' @var string
	public template_dir
	
	' The diretory where compiled templates are located
	' @var string
	public compile_dir
	
    ' The name of the directory for cache files.
    ' @var string
    public cache_dir
	
    ' The left delimiter used for the template tags.
    '	用于Simtpl_Compiler类
    ' @var string
    public left_delimiter

    ' The right delimiter used for the template tags.
    '	用于Simtpl_Compiler类
    ' @var string
    public right_delimiter
	
	' This enables template caching.
    ' <ul>
    '  <li>-1	= 数据缓存</li>
    '  <li>0	= 不缓存</li>
    '  <li>1	= 页面缓存</li>
    '  <li>2	= 内存缓存</li> 目前只支持TAIHOM解析
    ' </ul>
    ' @var integer
    public caching
	
    ' This is the number of seconds cached content will persist.
    ' <ul>
    '  <li>-1 = 永久缓存</li>
    '  <li> 0 = 不缓存</li>
    '  <li> N = 缓存N秒钟</li>	 
    ' </ul>
    ' @var integer
    public cache_lifetime
	
	' 内存的缓存周期，默认值cache_lifetime
	public mem_lifetime
	
	' 模板文件名的后缀
	public tpl_suffix
	
	
    ' 是否自动更新缓存文件，默认为开启
    ' @var string
	public auto_remove_cache
	
	
	' 是否使用带有控制器样式的tpl名称
	public use_ctrl_tpl
	
	' 过期的缓存数据，仍然使用
	public use_expiration
	
	' TAIHOM模板引擎
	Public taihom
	
	' 文件是否过期的数字表现形式，-1是重新生成，0为过期，1为在缓存期内
	Private is_cached__
	
	' 从缓存文件中获取的变量
	Private data_cache_vars
	
	Private is_use_assign
	
	Private is_use_simple_filename
	
	Public Property Get Show
		taihom.display()
		set taihom = nothing
		taihom = Empty
	End Property
	
	
	Public Property Get [Load](ByVal tpl)
		dim id
		if isArray( tpl ) then
			if ubound(tpl) > 0 then
				id = tpl(1)
			end if
			tpl = tpl(0)
		end if
		if tpl = "" Then
			tpl = POP_MVC.Url.get_action_name()
		End If
		if isEmpty(id) then
			id = tpl
		end if
		
		
		set taihom = P_("POPASP_TAIHOM")
		taihom.setCache = id & "," & caching & "," & cache_lifetime
		taihom.setTemplateFile = tpl
	End Property
	
    ' assigns values to template variables
    ' @param Dictionary|string tpl_var the template variable name(s)
    ' @param mixed value the value to assign
    public Sub assign( tpl_var, value )
		if not isEmpty( taihom ) Then
			taihom.d(tpl_var)=value
			exit sub
		end if
		dim arr,stype,bool	'arr为dictionary对象
		dim dict,i
		
		is_use_assign = true
		
		stype = typename(tpl_var)
		
		set arr = POP_MVC.Dict.Create()
		
		if stype = "Dictionary" Then	'没有分配value,直接将数组分配过来
            set arr = POP_MVC.dict.clone( tpl_var )
        elseif stype = "String" Then	'既有变量名,又有变量值
			bool = false
			if isArray(value) then
				if ubound(value)>=0 then
					if typename( value(0) ) = "Recordset" then
						dict_edit arr,tpl_var,rs2dict(value(0) )
						bool = true
					end if
				end if
			end if
			if not bool then
				select case typename(value)
					case "Recordset"
						dict_edit arr,tpl_var,POP_MVC.rs2dict(value)
					case else
						dict_edit arr,tpl_var,value
				end select
			end if
        End If
		set tpl_vars = dict_merge(tpl_vars,arr)
		set arr = nothing
    End Sub 'end Sub assign  
	
	
	'向内存中分配变量
	Public Sub mem_assign(byval key,value)
		on error resume next
		dim stype : stype = typename(value)
		dim apt_key,expire_key,bool
		apt_key = get_mem_key(key)
		expire_key = get_mem_expire_key(key)
		Application.unlock
		bool = false
		if isArray(value) then
			if ubound(value)>=0 then
				if typename( value(0) ) = "Recordset" then
					Application(apt_key) = js_encode(rs2dict(value(0) ))
					bool = true
				end if
			end if
		end if		
		if not bool then		
			if isDate(value) Then
				Application(apt_key) = CStr(value)
			elseif stype = "Dictionary" then
				Application(apt_key) = js_encode(value)
			elseif stype = "Recordset" then
				Application(apt_key) = js_encode( POP_MVC.rs2dict(value) )
			else 
				Application(apt_key) = value
			End If			
		end if
		Application(expire_key)= CStr( now() )
		Application.lock
		Call L_("POPASP_TEMPLATE.mem_assign")
	end sub ' end sub mem_assign
	

	
	' 凡是options变量都是可变参数
	Public Sub Display( byval options )
		' 不缓存时，直接用Display0
		
		Call G_("viewStartTime")
		if caching = 0 Then			 
			if isArray( options ) Then
				if UBound(options) = 0 Then
					Display0 options(0),""
				Else
					Display0 options(0),options(1)
				End if
			Else
				Display0 options,""
			End if		
		elseif caching<0 Then		' 数据缓存时，可以传入单个字符串tpl，也可以传入含有两个参数的数组 array(tpl,id)
			if isArray( options ) Then
				if UBound(options) = 0 Then
					Display_1 options(0),""
				Else
					Display_1 options(0),options(1)
				End if
			Else
				Display_1 options,""
			End if
		elseif caching>0 Then			 
			if isArray( options ) Then
				if UBound(options) = 0 Then
					Display1 options(0),""
				Else
					Display1 options(0),options(1)
				End if
			Else
				Display1 options,""
			End if		
		End If
	End Sub
	
	Public Sub Display0 ( tpl ,id )	
		'on error resume next
	
		caching = 0		
		if not is_empty( C_("SHOW_PAGE_TRACE") ) then
			POP_MVC.dTpl("缓存方式")="不缓存 C_(""TMPL_CACHING"")=0 " & P_("POPASP_PAGETRACE").help(C_("HELP_TMPL_CACHING") , "")
		end if
		
		if tpl = "" Then
			tpl = POP_MVC.Url.get_action_name()
		End If
		
		
		
		Dim compile_file : compile_file = get_compile_file(tpl)
		
Call G_("testStartTime")		
		'session_set用到了 js_encode  , 比较耗时，大约需要60ms
		Dim json_where : json_where = session_set( tpl , "" )
		
		If  Not is_temped(tpl , id) Then	
			call temp_put_json ( tpl , json_where , id )
		End If		

		' 如果模板文件未编绎，则先进行编绎，解析一次模板文件大约需要20ms
		if Not is_compiled(tpl) Then
			call compile_put_parse_context( tpl )
		End if
Call G_("testEndTime")		
		
		
		
		Call G_("ExecuteStartTime")
		Server.Execute compile_file	
		Call G_("ExecuteEndTime")
		
		Call L_("")
	End Sub
	
	Public Sub Display_1( ByRef tpl , ByRef id )
		dim data_cache_file
		if caching >=0 then
			Call POP_MVC.Exit( "请先开启缓存模式为-1，再使用 Display_1 " )
		end if
		
		if not is_empty( C_("SHOW_PAGE_TRACE") ) then
			POP_MVC.dTpl("缓存方式")="数据缓存 C_(""TMPL_CACHING"")=-1 " & P_("POPASP_PAGETRACE").help(C_("HELP_TMPL_CACHING") , "")
		end if
		
		if tpl = "" Then
			tpl = POP_MVC.Url.get_action_name()
		End If
	
		Dim compile_file : compile_file = get_compile_file(tpl)
		dim sess_key: sess_key = get_session_key( tpl )
		dim sess_where_key : sess_where_key = get_session_where_key(tpl)

		session(sess_key) = get_data_cache_file(tpl,id)
		session(sess_where_key) = 2		
	
	
	
		' 如果缓存有效，或者(缓存存在且可以使用过期缓存)
		if  not isEmpty(is_cached__)  AND is_cached__ >= 0  Then	
			Call data_cache_get_contents(tpl,id) '取得缓存文件数据
			set tpl_vars = dict_merge(data_cache_vars,tpl_vars)
		End If
		
		data_cache_file = get_data_cache_file( tpl,id )
		POP_MVC.dTpl("数据文件") = data_cache_file
		if not is_empty( C_("APP_DEBUG") ) then
			POP_MVC.dTpl("数据文件") = POP_MVC.dTpl("数据文件") & P_("POPASP_PAGETRACE").removeFile( data_cache_file , "删除数据文件" )
			POP_MVC.dTpl("数据文件") = POP_MVC.dTpl("数据文件") & P_("POPASP_PAGETRACE").removeFolder( cache_dir , "删除所有数据文件" )
			POP_MVC.dTpl("数据文件") = POP_MVC.dTpl("数据文件") & P_("POPASP_PAGETRACE").readFile( data_cache_file ,"查看数据文件" )
		end if	

		' 如果模板文件未编绎，则先进行编绎
		if Not is_compiled(tpl) Then			
			call compile_put_parse_context( tpl )
		End if	

		Call data_cache_put_contents( tpl,id )
		
		Call G_("ExecuteStartTime")
		Server.Execute compile_file	
		Call G_("ExecuteEndTime")	
	End Sub
	
	Public Sub Display1( ByRef tpl , ByRef id )
		on error resume next
		if caching <= 0 then
			Call POP_MVC.Exit( "请先开启缓存模式为1，再使用 Display1 " )
		end if
		
		if not is_empty( C_("SHOW_PAGE_TRACE") ) then
		POP_MVC.dTpl("缓存方式")="页面缓存 C_(""TMPL_CACHING"")=1 " & P_("POPASP_PAGETRACE").help(C_("HELP_TMPL_CACHING") , "")
		end if
		
		if tpl = "" Then
			tpl = POP_MVC.Url.get_action_name()
		End If
	
		Dim page_cache_file : page_cache_file = get_page_cache_file( tpl,id )
		Dim arr
		
	
		' 如果缓存有效，或者(缓存存在且可以使用过期缓存)
		if  not isEmpty(is_cached__)  AND is_cached__ >= 0  Then
		

			response.Buffer = True
			
			call PushInfo(tpl)
			
			if not is_empty( C_("APP_DEBUG") ) Then	
				POP_MVC.dTpl("缓存文件") = page_cache_file
				POP_MVC.dTpl("缓存文件") = POP_MVC.dTpl("缓存文件") & P_("POPASP_PAGETRACE").removeFile( page_cache_file , "删除缓存文件" )
				POP_MVC.dTpl("缓存文件") = POP_MVC.dTpl("缓存文件") & P_("POPASP_PAGETRACE").removeFolder( cache_dir , "删除所有缓存文件" )
			end if

			'Response.write与Server.Execute两种方法均可使用，经官网测试前者速度稍快一些
			Response.write MidB(file_get_contents(page_cache_file),3)
			'Server.Execute page_cache_file
		else
			caching = -1
			response.Buffer = True
			Call Display_1( tpl,id )
			if Request.QueryString(C_("TMPL_CACHE_ACTION"))<>C_("TMPL_CACHE_ACTION") then
				POP_MVC.Arr.Push arr,get_self_url()
				POP_MVC.Arr.Push arr,tpl
				POP_MVC.Arr.Push arr,id
				Call S_( array( C_("TMPL_CACHE_ACTION") , arr ) )
				Call A_( C_("TMPL_CACHE_ACTION") )
			end if
		End If
	End Sub
	
	'判断内存中是否存在某个键
	Public Function mem_exists(byval key)
		mem_exists =  (Not isEmpty(Application.Contents(get_mem_key(key))))		
	End Function
	
	Public Function mem_get( byval key )
		mem_get = Application.Contents(get_mem_key(key))
	end Function
	
	Public Sub mem_remove( key )
		Application.unlock
		Application.Contents.Remove(get_mem_key(key))
		Application.lock
	end Sub
	
	Public Function mem_cached(byval key)
		mem_cached = true
		if not mem_exists(key) then
			mem_cached = false
			exit Function
		end if
		if isEmpty(Application.Contents(get_mem_expire_key(key))) then
			mem_cached = false
			exit Function		
		end if
		if dateCompare( DateAdd("s",mem_lifetime, CDate(Application(get_mem_expire_key(key)) )) , now() ) < 0 then
			mem_cached = false
			exit Function
		end if
	End Function
	

	Public Function is_temped( byVal tpl ,ByVal id )
		dim template_file,temp_file,ctrl_file
		template_file	= get_template_file(tpl) 	'得到模板文件路径
		temp_file		= get_temp_file(tpl , id )	'得到临时文件路径
		
		is_temped = true
		
		' 如果编绎文件过期，临时文件也无效
		if not is_compiled( tpl ) Then
			is_temped = False
		End if		
		
		' 如果未分配变量，也返回 True
		If count(tpl_vars) = 0 Then 
			is_temped = true
			exit Function
		End If		
		

		'如果模板文件的修改时间大于临时文件文件的修改时间
		'		临时文件不存在			 ||   模板文件的修改时间>临时文件的修改时间
		If Not file_exists(temp_file) Then
			is_temped = false
			Exit Function
		ElseIf dateCompare(filemtime(template_file),filemtime(temp_file)) > 0 Then
			is_temped = false
			Exit Function
		End If '判断常规情况下临时文件是否失效
		
		' 控制器文件
		ctrl_file = get_ctrl_path( get_ctrl_name(tpl) )
		if ( file_exists(temp_file) AND file_exists(ctrl_file)) Then
			if dateCompare(filemtime(ctrl_file),filemtime(temp_file)) > 0 Then
				is_temped = false
				Exit Function
			End If
		End If	
		
	End Function
	
    ' test to see if valid cache exists for this template
    ' @param string tpl
    ' @param string id
	' if cached return true , or false
	Public function is_cached( byval tpl , byval id)
		if tpl = "" Then
			tpl = POP_MVC.Url.get_action_name()
		End If	

		if caching < 0 Then			
			is_cached = is_data_cached( tpl,id)			
		elseif caching >0 Then
			is_cached = is_page_cached( tpl,id)	
		else
			is_cached = false
		End if
	End Function
	
	Public Sub remove_compile( tpl )
		call POP_MVC.file.remove( get_compile_file(tpl) )
	End Sub
	
	Public Sub clear_compile()
		call POP_MVC.file.remove( compile_dir )
	End Sub
	
	public sub clear_cache()
		call POP_MVC.file.remove( cache_dir )	
	end sub
	
	' 清空内存
	Public Sub mem_clear()
		dim key
		Application.unlock
		for each key in Application.Contents	
			if POP_MVC.String.StartsWith( key, C_("TMPL_MEM_PREFIX") ) then
				Application.Contents.Remove(key)   
			end if
		next
		
		Application.lock
	End sub
	
	
	'清空与模板引擎相关的三个文件夹，compile_dir,temp_dir,cache_dir
	Public Sub clear()
		call POP_MVC.file.remove( compile_dir )
		call POP_MVC.file.remove( temp_dir )
		call POP_MVC.file.remove( cache_dir )
		call mem_clear
	End Sub
	
	' 清空指定app下的模板解析文件
	Public Sub clearCompileByAPP( appPath )
		call POP_MVC.file.remove( appPath & "/Runtime/Compile/" )
	End Sub
	
	' 清空指定app下的模板引擎相关的三个文件夹
	' appPath 是相对于入口文件的相对路径
	Public Sub clearByAPP( appPath )
		call POP_MVC.file.remove( appPath & "/Runtime/Temp/" )
		call POP_MVC.file.remove( appPath & "/Runtime/Compile/" )
		call POP_MVC.file.remove( appPath & "/Runtime/Cache/" )	
		call mem_clear
	End Sub
	
	'模板文件是否已经编绎
	function is_compiled( ByVal tpl )
		on error resume next
		dim template_file,compile_file,ctrl_file	

		call PushInfo(tpl)
		
		'调试阶段都为false
		if not is_empty( C_("APP_DEBUG") ) then
			is_compiled = false
			Exit Function
		end if
		
		template_file = get_template_file(tpl) 	'得到模板文件路径
		compile_file  = get_compile_file(tpl)	'得到编绎文件路径

		is_compiled = true

		'如果模板文件的修改时间大于编绎文件文件的修改时间
		'		编绎文件不存在			 ||   模板文件的修改时间>编绎文件的修改时间
		If Not file_exists(compile_file) Then
			is_compiled = false
			Exit Function
		ElseIf dateCompare(filemtime(template_file),filemtime(compile_file)) > 0 Then
			is_compiled = false
			Exit Function
		ElseIf Not is_empty( C_("APP_DEBUG") ) then		'如果处理调试阶段，还得看看popasp_template及其解析器是否修改过
			if dateCompare(filemtime(POP_MVC.mvc_dir & "popasp_template.class.asp"),filemtime(template_file)) > 0 Then
				is_compiled = false
				Exit Function
			ElseIf dateCompare(filemtime(POP_MVC.mvc_dir & "popasp_template_compiler.class.asp"),filemtime(template_file)) > 0 Then
				is_compiled = false
				Exit Function
			end if
		End If '判断常规情况下编绎文件是否失效

		ctrl_file = get_ctrl_path( get_ctrl_name(tpl) )

		if ( file_exists(compile_file) AND file_exists(ctrl_file)) Then
			if dateCompare(filemtime(ctrl_file),filemtime(compile_file)) > 0 Then
				is_compiled = false
				Exit Function
			End If
		End If
		call L_("")
	End Function 
	
	Private Function deleteLink( href,title )
		deleteLink = " <a href='" & href & "' target='_blank' style='color:red;text-decoration:none;' title='" & title & "'>&#215;</a>"
	End Function
	
	Private Function deleteAllLink( href,title )
		deleteAllLink = " <a href='" & href & "' target='_blank' style='color:red;text-decoration:none;' title='" & title & "'>※</a>"
	End Function	
	
	
	Private Function readLink( href,title )
		readLink   = " <a href='" & href & "' target='_blank' style='color:red;text-decoration:none;' title='" & title & "'>&#8801;</a>"
	end Function
	
	Sub PushInfo(tpl)
		on error resume next
		dim dTpl,url	
		template_file = get_template_file(tpl) 	'得到模板文件路径
		compile_file  = get_compile_file(tpl)	'得到编绎文件路径	
		
		set dTpl = POP_MVC.dTpl

		POP_MVC.dict.InsertAfter dTpl,"缓存方式","模板文件",template_file
		POP_MVC.dict.InsertAfter dTpl,"模板文件","解析文件",compile_file
		if not is_empty( C_("APP_DEBUG") ) Then	
			dTpl("模板文件") = dTpl("模板文件") & P_("POPASP_PAGETRACE").readFile(template_file,"查看模板文件")
			dTpl("解析文件") = dTpl("解析文件") & P_("POPASP_PAGETRACE").removeCompileFile(get_ctrl_name(tpl), get_action_name(tpl))
			dTpl("解析文件") = dTpl("解析文件") & P_("POPASP_PAGETRACE").clearCompileDir()
			dTpl("解析文件") = dTpl("解析文件") & P_("POPASP_PAGETRACE").readFile(compile_file,"查看解析文件")
		end if
		set POP_MVC.dTpl = dTpl	
		Call L_("")
	end sub
	
  
	'获取控制器文件的路径
	Private Function get_template_file( ByVal tpl )
		Dim template_file
		tpl = get_tpl_name( tpl )		
		template_file = template_dir  & tpl	
		
		if  Not file_exists(template_file) Then	'如果模板文件不存在
			get_template_file = Empty
		Else
			get_template_file = template_file
		End If
	End Function
  
    ' 获取tpl的完整名称
	' 为了得到这样的index/header.html，可以采用下列几种方式输入
    ' index/header.html
    ' index/header
	' header
	function get_tpl_name( tpl)
		dim c,a
		tpl = Replace(tpl, tpl_suffix, "" )
		if use_ctrl_tpl Then	
			c = get_ctrl_name(tpl)
			a = get_action_name(tpl)
			tpl = c & "/" & a		
		End If
		tpl = tpl & tpl_suffix
		get_tpl_name = tpl
	End Function
  
	'获得复杂的文件名
	Function get_poptpl_file_name ( tpl , id )
		dim str,length,trim_len,ret
		trim_len = 240

		length = Len(id)
		if length > 4096 then	'大于2048时直接用md5
			str = tpl & length & left(id,trim_len) & mid(id, int( sqr(length) ) , trim_len )  & mid(id, int( length/2 )- int(trim_len/2) , trim_len ) & mid(id, int( length ^ 0.95 ) , trim_len ) & right(id,trim_len)
			str = replace( str, " " , "" )
			str = replace( str, VBCRLF , "" )
			str = str & lenb(str)
			ret = Replace(Replace(tpl,"/","_"),TPL_SUFFIX,"") & "_" & md5(str)
		else
			str = replace( id, " " , "" )
			str = replace( str, VBCRLF , "" )
			ret = Replace(Replace(tpl,"/","_"),TPL_SUFFIX,"") & "_" & md5(str)
		end if
			
		get_poptpl_file_name = ret
	End Function
  
	'获取编绎模板路径
	Function get_compile_file( ByVal tpl )
		tpl = get_tpl_name( tpl )
		get_compile_file = compile_dir & get_poptpl_file_name(tpl,"") & ".asp"
	End Function
	
	function get_xml_file( tpl )
		get_xml_file = cache_dir & get_poptpl_file_name(get_tpl_name( tpl ),"") & ".xml" 
	end function
	
	Private Function get_tpl_vars_json ()
		if isEmpty( tpl_vars_json )  Then		
			tpl_vars_json = js_encode ( tpl_vars )	'高耗时函数
		End if
		get_tpl_vars_json = tpl_vars_json
	End Function
	
	'获取编绎模板路径
	Function get_temp_file( ByVal tpl ,ByVal id)
		dim str,temp
		tpl = get_tpl_name( tpl )
		if use_ctrl_tpl Then		
			str = get_ctrl_name(tpl) & get_action_name(tpl) & get_tpl_vars_json()
			get_temp_file = temp_dir & get_poptpl_file_name( tpl, id & str ) & ".asp"			
		else 
			get_temp_file = temp_dir & get_poptpl_file_name(tpl, id & get_tpl_vars_json() ) & ".asp"
		End If
	End Function


	
	' 将分配来的变量,输出到数据缓存文件
    ' 即将变量 $this->_tpl_vars 以json格式写入缓存文件,文件后缀名为dat
    ' @param string $html(cached page context)
	Private Sub data_cache_put_contents( tpl,id )
		if is_cached__ <= 0 Then			
			call data_put_contents(tpl,id,tpl_vars)	
		End If			
		exit Sub

		' 下面的算法在asp中不能实现
		if is_cached__ < 0 Then			
			dict_edit tpl_vars , "__is_cached__" , is_cached__
			call data_put_contents(tpl,id,tpl_vars)	
		Else
			
			if data_cache_vars.Exists("__is_cached__") Then	
				set data_cache_vars = POP_MVC.Dict( data_cache_vars, tpl_vars )
				data_cache_vars.remove("__is_cached__")					
				call data_put_contents( tpl,id,data_cache_vars)
			elseif is_cached__ = 0 then				
				dict_update data_cache_vars , tpl_vars 
				call data_put_contents( tpl,id,data_cache_vars)
			end if	
			
		end	if	
	End Sub ' end Sub data_cache_put_contents
	
	'将网页内容读出，并写入文件，页面缓存的关键方法
	Public Sub cache_url( )
		on error resume next
		dim content,arr,url,tpl,id,data_cache_file
		arr = S_( C_("TMPL_CACHE_ACTION") )
		if not isArray( arr ) then exit Sub
		url = arr(0)
		tpl = arr(1)
		id = arr(2)

		content = getUrlContent(url)
		
		'字符串内部的空行：(\s*?\r?\n\s*?)+
		content = POP_MVC.String.reg_replace(content,"","[\t]","gm")
		content = POP_MVC.String.reg_replace(content,"","($\s*$)|(^\s*^)|(\s(?=\s))","gm")
		content = POP_MVC.String.reg_replace(content,vbCrLf,"($\s+^)|(^\s+$)","gm")
		content = POP_MVC.String.reg_replace(content,"><",">\s+<","g")
		content = POP_MVC.String.reg_replace(content,">",">(\s+\n|\r)","g")
		if content <> "" Then
			call page_put_contents(tpl,id,content)	'将页面缓存数据写入文件
			data_cache_file = get_data_cache_file( tpl,id )
			call POP_MVC.file.remove( data_cache_file )	'删除数据缓存文件
		end if
	End Sub
	
	'获取当前网页的网址
	Private Function get_self_url( )
		dim protocol
		protocol = Request.ServerVariables("SERVER_PROTOCOL")
		get_self_url = LCase(POP_MVC.String.rtrim(protocol, POP_MVC.String.rstr(protocol,"/") )) & "://" & Request.ServerVariables("HTTP_HOST") 
		if C_("TMPL_PARSE_STRING.__SELF__") = "" Then
			get_self_url = get_self_url & "?" & C_("TMPL_CACHE_ACTION") & "=" & C_("TMPL_CACHE_ACTION")
		else
			get_self_url = get_self_url & C_("TMPL_PARSE_STRING.__SELF__") & "&" & C_("TMPL_CACHE_ACTION") & "=" & C_("TMPL_CACHE_ACTION")
		end if		
	End Function
	
	' 更新dict数据
	Private Sub dict_update ( byref dst_dict, byref src_dict )
		set dst_dict = POP_MVC.dict.update(dst_dict,src_dict)
	End Sub
	
	Function filemtime(filename)
		filemtime = POP_MVC.File.mtime(filename)
	End Function
  
	'如果date1>date2返回正，否则返回负数
	Function dateCompare( date1,date2 )
		dateCompare = DateDiff("s",date2,date1)
	End Function

	'判断文件或目录是否存在
	Function file_exists( fileName )
		file_exists = POP_MVC.File.isExists(fileName)
	End Function		
	
	' 将数据写入模板文件
	Private Sub data_put_contents( byRef tpl, byRef id, byRef data )
		file_put_contents get_data_cache_file(tpl,id),js_encode(data)
	End Sub
	
	' 将页面缓存写入模板文件
	Private Sub page_put_contents( byRef tpl, byRef id, byRef content )
		file_put_contents get_page_cache_file(tpl,id),content
	End Sub
	
	' 将数据缓存中的文件内容,与tpl_vars合并,后分配的会覆盖模板中已经有的
	Private sub data_cache_get_contents( byRef tpl,byRef id)		
		if file_exists(  get_data_cache_file(tpl,id) ) Then
			set data_cache_vars = js_decode(file_get_contents( get_data_cache_file(tpl,id) ))
		else 
			set data_cache_vars = POP_MVC.Dict.Create()
		End If			
	End Sub 'end Sub data_cache_get_contents	
	
	
    '判断是否数据缓存
    ' @param string $tpl
    ' @如果开启数据缓存,且数据缓存有效,则返回 True
	Private function is_data_cached( byval tpl,byval id)
		dim template_file,data_cache_file,ctrl_file
		is_data_cached = Empty		
		if caching < 0 Then '如果开启数据缓存
			
			template_file = get_template_file(tpl) 	'得到模板文件路径
			data_cache_file = get_data_cache_file(tpl,id)	'得到数据缓存文件路径
			ctrl_file = get_ctrl_path( get_ctrl_name(tpl) )
			
			'		缓存文件不存在		       ||   控制器文件修改了
			if Not file_exists(data_cache_file)  Then
				is_data_cached = false
				is_cached__ = -1	'需要重新生成数据文件
				Exit Function			
			elseif dateCompare(filemtime(ctrl_file),filemtime(data_cache_file)) > 0 Then			
				is_data_cached = false
				is_cached__ = -1	'需要重新生成数据文件
				Exit Function
			ElseIf dateCompare(now(),filemtime(data_cache_file)) > cache_lifetime Then	
				is_data_cached = false
				is_cached__ = 0		'需要更新数据文件中的数据
				Exit Function
			End If
			is_data_cached = true
			is_cached__ = 1		'
		End If		
	End Function
	
	
    '判断是否页面缓存
    ' @param string $tpl
    ' @如果开启页面缓存,且页面缓存有效,则返回 True
	function is_page_cached( byval tpl,byval id)
		dim template_file,page_cache_file,ctrl_file
	
		if caching > 0 Then '如果开启页面缓存				
			template_file = get_template_file(tpl) 	'得到模板文件路径
			page_cache_file = get_page_cache_file(tpl,id)	'得到页面缓存文件路径
			POP_MVC.dTpl("缓存文件") = POP_MVC.realPath(page_cache_file)
			ctrl_file = get_ctrl_path( get_ctrl_name(tpl) )
			'		缓存文件不存在		       ||   控制器文件修改了
			if Not file_exists(page_cache_file)  Then
				is_page_cached = false
				is_cached__ = -1	'需要重新生成缓存文件
				Exit Function
			ElseIf dateCompare(now(),filemtime(page_cache_file)) > cache_lifetime Then	
				is_page_cached = false
				is_cached__ = -1		'需要重新生成缓存文件
				Exit Function
			End If
			is_page_cached = true
			is_cached__ = 1		'
		End If	
	End Function
	
	' 得到数据缓存文件路径
	Private function get_data_cache_file( byVal tpl , byVal id )
		get_data_cache_file = cache_dir & get_poptpl_file_name(get_tpl_name( tpl ),id) & ".asp" '得到如smarty那样复杂的命名
	End Function 'end function _get_data_cache_file
	
	Function get_page_cache_file( byVal tpl , byVal id )
		get_page_cache_file = cache_dir & get_poptpl_file_name(get_tpl_name( tpl ),id) & ".asp.html" '得到如smarty那样复杂的命名
	End Function 'end function _get_data_cache_file
	
	Private Sub session_remove( tpl )
		session.contents.remove( get_session_key( tpl ) )
		session.contents.remove( get_session_where_key(tpl) )
	End Sub
	
	' 设置session
	Private Function session_set ( tpl , id)

		dim sess_key: sess_key = get_session_key( tpl )
		dim sess_where_key : sess_where_key = get_session_where_key(tpl)
		dim temp_file,url,len_vars
		if count( tpl_vars ) > 0 Then
			session_length = CLng( session_length )

			len_vars = LenB( get_tpl_vars_json() )
				
			if len_vars < session_length Then	'保存到session中
				session_set = 1
				session(sess_where_key) = 1
				
				
				
				session(sess_key) = get_tpl_vars_json()
				
				
				
				POP_MVC.dTpl("数据文件") = "session(""" & sess_key &  """)" 
				if not is_empty( C_("APP_DEBUG") ) then
					POP_MVC.dTpl("数据文件") = POP_MVC.dTpl("数据文件") & P_("POPASP_PAGETRACE").removeSession( sess_key,"删除数据文件" )
					POP_MVC.dTpl("数据文件") = POP_MVC.dTpl("数据文件") & P_("POPASP_PAGETRACE").readSession( sess_key,"查看数据文件" )
					POP_MVC.dTpl("数据大小") = " ( assign " & P_("POPASP_PAGETRACE").help(C_("HELP_ASSIGN"),"") & " ) " & len_vars & " &lt; " & session_length & " ( session_length ) "
				end if					
			else	'保存到文件中				
				session_set = 2
				session(sess_where_key) = 2
				if caching = 0 Then
					temp_file = get_temp_file(tpl,id)
					session(sess_key) = temp_file					

					POP_MVC.dTpl("数据文件") = POP_MVC.realpath(temp_file)
					if not is_empty( C_("APP_DEBUG") ) then
						POP_MVC.dTpl("数据文件") = POP_MVC.dTpl("数据文件") & P_("POPASP_PAGETRACE").removeFile(temp_file,"删除数据文件")
						POP_MVC.dTpl("数据文件") = POP_MVC.dTpl("数据文件") & P_("POPASP_PAGETRACE").removeFolder( temp_dir , "删除所有数据文件" )
						POP_MVC.dTpl("数据文件") = POP_MVC.dTpl("数据文件") & P_("POPASP_PAGETRACE").readFile(temp_file, "查看数据文件")
						POP_MVC.dTpl("数据大小") = " ( assign " & P_("POPASP_PAGETRACE").help(C_("HELP_ASSIGN"),"") & " ) " & len_vars & " &ge; " & session_length & " ( session_length ) "
					end if					
				elseif caching < 0 Then
					session(sess_key) = get_data_cache_file(tpl,id)
				else 
					session(sess_key) = get_page_cache_file(tpl,id)
				End if				
			End if
			
			
		else	'不设置session
			session_set = 0
			Session.Contents.Remove(sess_key)
			Session.Contents.Remove(sess_where_key)
		End if
	End Function
	
	
    ' put json and .html to temp file
    ' param string tpl
	Private Sub temp_put_json ( tpl ,json_where , id )
		If json_where = 2 Then
			call file_put_contents( get_temp_file(tpl ,id) , get_tpl_vars_json () )
		End If		
	End Sub
	
    ' put replace context to compile file
    ' param string $context(replace context)
	Private Sub compile_put_parse_context( tpl )
		dim contents,compile_file
		dim sess_key : sess_key = get_session_key(tpl)
		dim sess_where_key : sess_where_key = get_session_where_key(tpl)
		contents = ""
		contents = contents & file_get_contents( POP_MVC.mvc_dir & "Tpl/poplite.inc.txt" ) & vbCrLf
		contents = Replace( contents,"POPLITE_PATH", poplite_path ) '  包含 lasp.asp 文件(include 方式)
		contents = Replace( contents,"POPLITE_MVC_DIR", POP_MVC.ltrim(POP_MVC.mvc_dir,"./") ) '  包含 mvc_dir
		contents = Replace( contents,"TPL_NAME", tpl ) '  TPL
		contents = Replace( contents,"SESS_WHERE_KEY", sess_where_key ) ' 替换 sess_where_key
		contents = Replace( contents,"SESS_KEY", sess_key )	' 替换 sess_key			
		contents = Replace( contents,"TMPL_MEM_PREFIX", C_("TMPL_MEM_PREFIX") )	' 替换 TMPL_MEM_PREFIX			
		contents = Replace( contents,"STARTTIME", POP_MVC.dG_("beginTime") )	' 替换 TMPL_MEM_PREFIX		
		
		' 4.得到模板解析后的内容	
		contents = contents & get_parse_context( tpl )
		contents = contents & Chr(13) & Chr(10) & "<" & "!--#include file=""" & poplite_end_path  & """ --" & ">"
		contents =  POP_MVC.String.reg_replace(contents,"","^\s+|\s+$","ig")
		
		
		call file_put_contents(get_compile_file(tpl),contents) '将内容写入文件
	End Sub 'end Sub compile_put_parse_context
	
	' 获取session中用到的键值
	Private Function get_session_key ( tpl )
		if use_ctrl_tpl Then
			get_session_key = APP_PATH & "/" & get_ctrl_name( tpl ) & "/" & get_action_name( tpl )
		else 
			get_session_key = APP_PATH & "/" & get_action_name( tpl )
		End if
	End Function
	
	' 获取session中用到的键值
	Private Function get_session_where_key ( tpl ) 
		get_session_where_key = get_session_key(tpl) & "_where"
	End Function
	
	' 获取字典对象中的元素个数
	Private Function count( byref dict ) 
		count = dict.Count
	End Function
	
	sub handler_template_file_not_exists( tpl )
		on error resume next
		Err.Raise 1000,"自定义错误"," 未找到模板 " & tpl & " "
		Call L_("")
	end sub
	
	Private Function get_parse_layout_include( context ,first )
		dim matches,pattern
		dim layout_on_ : layout_on_ = layout_on
		dim layout_file_ : layout_file_ = layout_file
		dim layout_context
		dim include_file,include_context
		dim i,j : j=0
		dim bool:bool = false

		if inStr( context,nolayout_label ) > 0 then
			context = replace( context,nolayout_label,"" )	'替换 nolayout_label
			context = replace( context,layout_label,"" )	'替换 layout_label
		else
			pattern = left_delimiter & "\s*layout\s+(?:file|name\s*=\s*)?(""|" & chr(39) & "|)(.*?)\1\s*" & right_delimiter
		
			' layout 文件的处理
			j = 0
			do while ( POP_MVC.String.reg_test(context,pattern,"i") and j<100 )				
				set matches = POP_MVC.reg.Execute( context )
				layout_file_ = matches(0).SubMatches(1)
				layout_file_ = get_template_file(layout_file_)	'得到layout文件路径
				if not isEmpty( layout_file_ ) then
					layout_context = file_get_contents(layout_file_)	'得到layout文件内容
					context = replace( layout_context,layout_label,context )	'替换{__CONTENT__}
					context = replace( context, matches(0), ""  )
					bool = true	
				else
					context = replace( context,matches(0),"<!-- 未找到layout文件:" & matches(0).SubMatches(1) & " -->" )	'替换
					call handler_template_file_not_exists( matches(i).SubMatches(1) )					
				end if		
				j = j+1
			loop					
			
			'ThinkPHP中 layout 文件的处理
			pattern = "<\s*layout\s+(?:file|name)\s*=\s*(""|" & chr(39) & "|)(.*?)\1\s*/>"
			
			j = 0
			do while (POP_MVC.String.reg_test(context,pattern,"i") and j<100 )
				set matches = POP_MVC.reg.Execute( context )
				layout_file_ = matches(0).SubMatches(1)
				layout_file_ = get_template_file(layout_file_)	'得到layout文件路径
				if not isEmpty( layout_file_ ) then
					layout_context = file_get_contents(layout_file_)	'得到layout文件内容
					context = replace( layout_context,layout_label,context )	'替换{__CONTENT__}
					context = replace( context, matches(0), ""  )
					bool = true	
				else
					context = replace( context,matches(0),"<!-- 未找到layout文件:" & matches(0).SubMatches(1) & " -->" )	'替换
					call handler_template_file_not_exists( matches(i).SubMatches(1) )					
				end if
				j = j+1
			loop			
			

			if layout_on_ and layout_file_ <> "" and not bool and first then	
				layout_file_ = get_template_file(layout_file_)	'得到layout文件路径
				layout_context = file_get_contents(layout_file_)	'得到layout文件内容				
				context = replace( layout_context,layout_label,context )	'替换{__CONTENT__}				
			end if
			
		end if
		
		
		'include文件的处理	
		pattern = left_delimiter & "\s*include\s+(?:file\s*=\s*)?(""|" & chr(39) & "|)(.*?)\1\s*" & right_delimiter	
		do while (POP_MVC.String.reg_test(context,pattern,"gi") and j<2000 )
			set matches = POP_MVC.reg.Execute( context )
			for i = 0 to matches.count-1
				include_file = matches(i).SubMatches(1)
				include_file = get_template_file(include_file)	'得到 include 文件路径
				if not isEmpty( include_file ) then
					include_context = file_get_contents(include_file)	'得到 include 文件内容
					context = replace( context,matches(i),include_context )	'替换
				else
					context = replace( context,matches(i),"<!-- 未找到include文件:" & matches(i).SubMatches(1) & " -->" )	'替换
					call handler_template_file_not_exists( matches(i).SubMatches(1) )
				end if
			next			
			j = j+1
		loop
		set matches = nothing
		
		
		
		'ThinkPHP中include文件的处理
		pattern = "<\s*include\s+file\s*=\s*(""|" & chr(39) & "|)(.*?)\1\s*\/>"
		j = 0		
		do while ( POP_MVC.String.reg_test(context,pattern,"gi") and j<2000 )			
			set matches = POP_MVC.reg.Execute( context )
			for i = 0 to matches.count-1
				include_file = matches(i).SubMatches(1)				
				include_file = replace(include_file,":", C_("TMPL_FILE_DEPR") )					
				include_file = get_template_file(include_file)	'得到 include 文件路径	
				
				if not isEmpty( include_file ) then
					include_context = file_get_contents(include_file)	'得到 include 文件内容
					context = replace( context,matches(i),include_context )	'替换
				else
					context = replace( context,matches(i),"<!-- 未找到include文件:" & matches(i).SubMatches(1) & " -->" )	'替换
					call handler_template_file_not_exists( matches(i).SubMatches(1) )
				end if
			next			
			j = j+1
		loop
		set matches = nothing
		get_parse_layout_include = context
	end Function
	
	function get_tpl_context( tpl )
		dim template_file,context
		template_file =  get_template_file(tpl)	'得到模板文件路径
		
		context = file_get_contents(template_file)	'得到模板文件内容		
		
		context = get_parse_layout_include( context ,true )
		context = get_parse_layout_include( context , false )
		context = get_parse_layout_include( context , false  )
		context = get_parse_layout_include( context , false  )
		get_tpl_context = context
	end function

  
    ' sets PHP tag to the compiled source
    ' @param string $tpl(template file)
	Private function get_parse_context ( tpl ) 
		Call G_("compileStartTime")
		dim template_file,context,newtext
		dim compiler
		
		template_file =  get_template_file(tpl)	'得到模板文件路径
		
		context = get_tpl_context( tpl )	
		
		
		'Response.end
		
		
		

		' 下面要使用解析器对模板文件进行解析了		
		set compiler = P_("TEMPLATE_COMPILER")
		compiler.init left_delimiter,right_delimiter,C_("TMPL_COMPILE_TPL_NAME")
		compiler.set "template",get_tpl_name(tpl)
		compiler.set "compiler",get_poptpl_file_name(tpl,"") & ".asp"

		newtext = compiler.compile( context )
		

		
		'POP_MVC.echo newtext	
		'response.end

		'解析文件内容完成

		if ( ""<>trim(context) AND ""=trim(newtext)) Then
			Call POP_MVC.Exit( "模板引擎不能正常解析" & template_file & "文件,出现该问题的原因有可能是:1,文件编码未采用无BOM的utf-8;2,未依据poptpl要求进行编写模板文件" )
		End If
		get_parse_context = newtext
		Call G_("compileEndTime")	
	End Function 'end function get_parse_context
	
	' 类似于PHP中的array_merge
	Private Function dict_merge( byref dict1,byref dict2 )
		set dict_merge = POP_MVC.dict.merge(dict1,dict2)
	End Function
	
	' 给dict中添加一个键值对
	Private Sub dict_edit( byref dict,byval key,byref val)
		POP_MVC.dict.edit dict,key,val
	End Sub

	' 给文件写入内容，如果文件不存在，则尝试创建
	private Function file_put_contents(filename,content)
		file_put_contents = POP_MVC.file_put_contents(filename,content)
	end Function
  
  
	'从模板名中得到控制器名称
	Private Function get_ctrl_name(tpl_name)
		get_ctrl_name = POP_MVC.get_ctrl_name(tpl_name)
	End Function
  
	'从模板名中得到操作名称
	Private Function get_action_name(tpl_name)
		get_action_name = POP_MVC.get_action_name(tpl_name)
	End Function
  
	'获取控制器文件的路径
	Private Function get_ctrl_path( ctrl_name )
		get_ctrl_path = POP_MVC.get_ctrl_path( ctrl_name )
	End Function
	
	Private Sub echo ( str )
		call POP_MVC.echo(str)
	End Sub

	Private Sub Class_Terminate		
		set tpl_vars = nothing
		set fso = nothing
		set data_cache_vars = nothing
	End Sub  
	
	Private Sub Class_Initialize
		set tpl_vars = POP_MVC.Dict.Create()
		set fso = POP_MVC.fso
		
		
		'是否启用模板布局
		layout_on = false
		
		layout_label = "{__CONTENT__}"
		
		nolayout_label = "{__NOLAYOUT__}"
		
		'模板布局文件
		layout_file = ""
		
		' session 中允许的最大字符个数
		session_length = 0
		
		' The name of the diretory where temp file are located
		' @var string
		temp_dir = "./temp/"

		' The name of the diretory where templates are located
		template_dir = "./templates/"

		' The diretory where compiled templates are located
		compile_dir = "./compiles/"

		' The name of the directory for cache files.
		cache_dir		=	"./cache/"

		' The left delimiter used for the template tags.
		left_delimiter  =  "{"

		' The right delimiter used for the template tags.
		right_delimiter =  "}"

		' This enables template caching.
		caching         =  0

		' This is the number of seconds cached content will persist.
		cache_lifetime  =  3600	
		
		mem_lifetime = cache_lifetime

		' 模板文件名的后缀
		tpl_suffix = ".html"

		' 是否自动更新缓存文件，默认为开启
		auto_remove_cache = 1

		' 过期的缓存数据，仍然使用
		use_expiration = false
		
		' 是否使用带有控制器样式的tpl名称
		use_ctrl_tpl = true
		
		is_use_assign = false
		
		is_use_simple_filename = true
		
		call init
	End Sub
	
	'获取某个网页的内容
	Function GetUrlContent( weburl )
		GetUrlContent = BytesToBstr(GetBody( weburl ),"UTF-8")	
	End Function
	
	'获取某个网页的内容
	Private Function GetBody(weburl)
		'创建对象 
		Dim ObjXMLHTTP 
		'Server.ScriptTimeout = 2
		Set ObjXMLHTTP=Server.CreateObject(C_("XMLHTTP") ) 
		
		'请求文件,以异步形式 
		ObjXMLHTTP.Open "POST",weburl,true 
		ObjXMLHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
		ObjXMLHTTP.send 
		While ObjXMLHTTP.readyState <> 4 
			ObjXMLHTTP.waitForResponse 1000 
		Wend
		'得到结果 
		 GetBody=ObjXMLHTTP.responseBody 
		'释放对象 
		 Set ObjXMLHTTP=Nothing 
	End Function

	'将流内容转化成指定编码格式的文本
	Private Function BytesToBstr(body,Cset) 
		dim objstream 
		set objstream = Server.CreateObject("adodb.stream") 
		objstream.Type = 1 
		objstream.Mode =3 
		objstream.Open 
		objstream.Write body 
		objstream.Position = 0 
		objstream.Type = 2 
		objstream.Charset = Cset 
		BytesToBstr = objstream.ReadText  
		objstream.Close 
		set objstream = nothing 
	End Function
	
	Function get_mem_key(key)
		get_mem_key = C_("TMPL_MEM_PREFIX") & key	
	End Function
	
	Private Function get_mem_expire_key(key)
		get_mem_expire_key = C_("TMPL_MEM_PREFIX") & "__POPASP_EXPIRE_START__" & key	& "__POPASP_EXPIRE_END__"
	End Function
	
	' 将Recordset结果集转化成Dictionary，每行记录的键名均为数字类型，且为Dictionary类型
	Public Function rs2dict(rs)
		dim i,k,dict,start,sql,j:j=0
	
		set rs2dict = D_
		
		if not is_empty( C_("SHOW_PAGE_TRACE") ) Then
			start = timer()	
		end if		
		
		if POP_MVC.String.reg_test(rs.Source,"^\s*SELECT\s+TOP\s+1\s+.+|^\s*SELECT\s+.*?LIMIT\s+1\s*;?$","gi") then
			set dict = D_						
			for i = 0 to rs.fields.count-1
				dict( rs.Fields(i).Name ) = rs.Fields(i).Value 
			next						
			set rs2dict = dict
		else
			set rs2dict = D_
			for k = 1 to rs.pageSize		
				if not rs.BOF and not rs.EOF Then					
					set dict = D_
					for i = 0 to rs.fields.count-1
						dict( rs.Fields(i).Name ) = rs.Fields(i).Value 
					next
					rs2dict.add j,dict
					rs.MoveNext
					j = j+1
				end If
			next
		end if
		
		if not is_empty( C_("SHOW_PAGE_TRACE") ) Then
			set sql = D_
			sql("time") = round((timer() - start) * 1000,0)
			sql("sql") = rs.Source & " ; -- Recordset to Dictionary "
			POP_MVC.Dict.Push dSql,"",sql
		end if		
		set dict = nothing
	End Function
	
	Private Sub init()
		layout_on		= C_("TMPL_LAYOUT_ON")
		layout_file	= C_("TMPL_LAYOUT_FILE")
		layout_label	= C_("TMPL_LAYOUT_LABEL")
		nolayout_label	= C_("TMPL_NOLAYOUT_LABEL")
		caching		= C_("TMPL_CACHING")
		cache_lifetime = C_("TMPL_CACHE_LIFETIME")
		
		session_length = C_("TMPL_SESSION_LENGTH")
		
		mem_lifetime = cache_lifetime
		poplite_end_path	= "../../../" & POP_MVC.ltrim(POP_MVC.mvc_dir,"./") & "tpl/poplite_end.inc.txt"
		poplite_path	= "../../../" & POP_MVC.ltrim(POP_MVC.mvc_dir,"./") & "lasp.asp"

		
		left_delimiter		= POP_MVC.getConfig("TMPL_L_DELIM")
		right_delimiter	= POP_MVC.getConfig("TMPL_R_DELIM")
		tpl_suffix			= POP_MVC.getConfig("TMPL_TEMPLATE_SUFFIX")
		
		
		'下面这几项是MVC配置好的
		template_dir	= APP_PATH & "/Tpl/"
		temp_dir		= APP_PATH & "/Runtime/Temp/"
		compile_dir 	= APP_PATH & "/Runtime/Compile/"
		cache_dir	 	= APP_PATH & "/Runtime/Cache/"		
	End sub
End Class
%>